package com.ecommerce.chat.service;

import com.ecommerce.chat.dto.ChatRequest;
import com.ecommerce.chat.dto.ChatResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 异步任务管理器
 * 专为小程序设计的异步聊天任务管理，支持任务状态跟踪和结果获取
 * 
 * @author AI客服系统
 */
@Slf4j
@Component
public class AsyncTaskManager {
    
    /**
     * 任务状态枚举
     */
    public enum TaskStatus {
        PENDING("pending", "等待处理"),
        PROCESSING("processing", "处理中"),
        COMPLETED("completed", "已完成"),
        FAILED("failed", "处理失败"),
        EXPIRED("expired", "已过期");
        
        private final String code;
        private final String description;
        
        TaskStatus(String code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 异步任务信息
     */
    @Data
    public static class AsyncTask {
        private String taskId;
        private ChatRequest request;
        private TaskStatus status;
        private ChatResponse result;
        private String errorMessage;
        private LocalDateTime createTime;
        private LocalDateTime updateTime;
        private CompletableFuture<ChatResponse> future;
        
        public AsyncTask(String taskId, ChatRequest request) {
            this.taskId = taskId;
            this.request = request;
            this.status = TaskStatus.PENDING;
            this.createTime = LocalDateTime.now();
            this.updateTime = LocalDateTime.now();
        }
        
        public void updateStatus(TaskStatus status) {
            this.status = status;
            this.updateTime = LocalDateTime.now();
        }
        
        public void setResult(ChatResponse result) {
            this.result = result;
            this.status = TaskStatus.COMPLETED;
            this.updateTime = LocalDateTime.now();
        }
        
        public void setError(String errorMessage) {
            this.errorMessage = errorMessage;
            this.status = TaskStatus.FAILED;
            this.updateTime = LocalDateTime.now();
        }
    }
    
    // 任务存储，使用ConcurrentHashMap保证线程安全
    private final ConcurrentHashMap<String, AsyncTask> tasks = new ConcurrentHashMap<>();
    
    // 定时清理过期任务
    private final ScheduledExecutorService cleanupExecutor = Executors.newSingleThreadScheduledExecutor();
    
    // 任务过期时间（分钟）
    private static final int TASK_EXPIRE_MINUTES = 30;
    
    public AsyncTaskManager() {
        // 每5分钟清理一次过期任务
        cleanupExecutor.scheduleAtFixedRate(this::cleanupExpiredTasks, 5, 5, TimeUnit.MINUTES);
    }
    
    /**
     * 创建异步任务
     * 
     * @param request 聊天请求
     * @return 任务ID
     */
    public String createTask(ChatRequest request) {
        String taskId = generateTaskId();
        AsyncTask task = new AsyncTask(taskId, request);
        tasks.put(taskId, task);
        
        log.info("创建异步任务: {}, 消息: {}", taskId, request.getMessage());
        return taskId;
    }
    
    /**
     * 获取任务信息
     * 
     * @param taskId 任务ID
     * @return 任务信息，不存在返回null
     */
    public AsyncTask getTask(String taskId) {
        return tasks.get(taskId);
    }
    
    /**
     * 更新任务状态
     * 
     * @param taskId 任务ID
     * @param status 新状态
     */
    public void updateTaskStatus(String taskId, TaskStatus status) {
        AsyncTask task = tasks.get(taskId);
        if (task != null) {
            task.updateStatus(status);
            log.debug("任务状态更新: {} -> {}", taskId, status.getCode());
        }
    }
    
    /**
     * 设置任务结果
     * 
     * @param taskId 任务ID
     * @param result 聊天响应结果
     */
    public void setTaskResult(String taskId, ChatResponse result) {
        AsyncTask task = tasks.get(taskId);
        if (task != null) {
            task.setResult(result);
            log.info("任务完成: {}, 响应长度: {}", taskId, 
                result.getReply() != null ? result.getReply().length() : 0);
        }
    }
    
    /**
     * 设置任务错误
     * 
     * @param taskId 任务ID
     * @param errorMessage 错误信息
     */
    public void setTaskError(String taskId, String errorMessage) {
        AsyncTask task = tasks.get(taskId);
        if (task != null) {
            task.setError(errorMessage);
            log.error("任务失败: {}, 错误: {}", taskId, errorMessage);
        }
    }
    
    /**
     * 设置任务的CompletableFuture
     * 
     * @param taskId 任务ID
     * @param future CompletableFuture对象
     */
    public void setTaskFuture(String taskId, CompletableFuture<ChatResponse> future) {
        AsyncTask task = tasks.get(taskId);
        if (task != null) {
            task.setFuture(future);
        }
    }
    
    /**
     * 检查任务是否存在
     * 
     * @param taskId 任务ID
     * @return 是否存在
     */
    public boolean taskExists(String taskId) {
        return tasks.containsKey(taskId);
    }
    
    /**
     * 获取任务状态
     * 
     * @param taskId 任务ID
     * @return 任务状态，不存在返回null
     */
    public TaskStatus getTaskStatus(String taskId) {
        AsyncTask task = tasks.get(taskId);
        return task != null ? task.getStatus() : null;
    }
    
    /**
     * 获取任务结果
     * 
     * @param taskId 任务ID
     * @return 任务结果，未完成或不存在返回null
     */
    public ChatResponse getTaskResult(String taskId) {
        AsyncTask task = tasks.get(taskId);
        return task != null && task.getStatus() == TaskStatus.COMPLETED ? task.getResult() : null;
    }
    
    /**
     * 获取任务错误信息
     * 
     * @param taskId 任务ID
     * @return 错误信息，无错误或不存在返回null
     */
    public String getTaskError(String taskId) {
        AsyncTask task = tasks.get(taskId);
        return task != null && task.getStatus() == TaskStatus.FAILED ? task.getErrorMessage() : null;
    }
    
    /**
     * 删除任务
     * 
     * @param taskId 任务ID
     */
    public void removeTask(String taskId) {
        AsyncTask task = tasks.remove(taskId);
        if (task != null) {
            // 如果任务还在执行，尝试取消
            if (task.getFuture() != null && !task.getFuture().isDone()) {
                task.getFuture().cancel(true);
            }
            log.debug("删除任务: {}", taskId);
        }
    }
    
    /**
     * 获取当前任务数量
     * 
     * @return 任务数量
     */
    public int getTaskCount() {
        return tasks.size();
    }
    
    /**
     * 清理过期任务
     */
    private void cleanupExpiredTasks() {
        LocalDateTime expireTime = LocalDateTime.now().minusMinutes(TASK_EXPIRE_MINUTES);
        int cleanedCount = 0;
        
        for (String taskId : tasks.keySet()) {
            AsyncTask task = tasks.get(taskId);
            if (task != null && task.getCreateTime().isBefore(expireTime)) {
                // 标记为过期
                task.updateStatus(TaskStatus.EXPIRED);
                // 取消未完成的任务
                if (task.getFuture() != null && !task.getFuture().isDone()) {
                    task.getFuture().cancel(true);
                }
                // 删除过期任务
                tasks.remove(taskId);
                cleanedCount++;
            }
        }
        
        if (cleanedCount > 0) {
            log.info("清理过期任务: {} 个，剩余任务: {} 个", cleanedCount, tasks.size());
        }
    }
    
    /**
     * 生成任务ID
     * 
     * @return 唯一任务ID
     */
    private String generateTaskId() {
        return "task_" + UUID.randomUUID().toString().replace("-", "");
    }
    
    /**
     * 关闭资源
     */
    public void shutdown() {
        cleanupExecutor.shutdown();
        try {
            if (!cleanupExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                cleanupExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            cleanupExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        
        // 取消所有未完成的任务
        for (AsyncTask task : tasks.values()) {
            if (task.getFuture() != null && !task.getFuture().isDone()) {
                task.getFuture().cancel(true);
            }
        }
        tasks.clear();
        
        log.info("AsyncTaskManager 已关闭");
    }
}